<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>8.WebGL 填充多边形</title>
    <style>
        canvas{
            border:1px solid #aaa;
            margin: 0 auto;
            display: block;
        }
    </style>
</head>
<body>
    <canvas width="800" height="800"></canvas>

    <script type="module">
        // 导入进行三角剖分的库
        import { earcut } from '../common/lib/earcut.js';

        const canvas = document.querySelector("canvas")
        const gl = canvas.getContext("webgl")

        const vertex = ` 
            attribute vec2 position; 
            void main() { 
                gl_PointSize = 1.0; 
                gl_Position = vec4(position, 1.0, 1.0); 
            }
        `;
        const fragment = ` 
            precision mediump float; 
            void main() { 
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
            } 
        `;
        
        // 创建顶点着色器对象
        const vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertexShader, vertex);
        gl.compileShader(vertexShader);

        // 创建片元着色器对象
        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader, fragment);
        gl.compileShader(fragmentShader);

        // 2. 创建 WebGLProgram 对象
        const program = gl.createProgram();
        // 添加 vertexShader 和 fragmentShader
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);

        // 将这个 WebGLProgram 对象链接到 WebGL 上下文对象上
        gl.linkProgram(program);

        // 通过 useProgram 选择启用这个 WebGLProgram 对象，这样，当我们绘制图形时，GPU 就会执行我们通过 WebGLProgram 设定的 两个 shader 程序了。
        gl.useProgram(program);



        // 不规则多边形的顶点数组
        const vertices = [
            [-0.7, 0.5],
            [-0.4, 0.3],
            [-0.25, 0.71],
            [-0.1, 0.56],
            [-0.1, 0.13],
            [0.4, 0.21],
            [0, -0.6],
            [-0.3, -0.3],
            [-0.6, -0.3],
            [-0.45, 0.0],
        ];

        // 扁平化顶点数组
        const points = vertices.flat();

        // 进行三角剖分；triangles是下标数组，这个数组的值是顶点数组vertices数据的 index
        const triangles = earcut(points);
        
        // 将顶点数组和index下标数组都存入缓存区
        const position = new Float32Array(points);
        const cells = new Uint16Array(triangles);

        const pointBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, pointBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, position, gl.STATIC_DRAW);

        const vPosition = gl.getAttribLocation(program, 'position');
        gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(vPosition);

        const cellsBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cellsBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cells, gl.STATIC_DRAW);

        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.drawElements(gl.TRIANGLES, cells.length, gl.UNSIGNED_SHORT, 0);
        
    </script>
</body>
</html>